﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using ZhongKeSite.Common;
using ZhongKeSite.Common.Helper;
using ZhongKeSite.Entity;
using ZhongKeSite.Service;

namespace ZhongKeSite.Web.Models
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    public class RoleAuthorizeAttribute : ActionFilterAttribute, IAuthorizationFilter
    {
        /// <summary>
        /// 判断权限值
        /// 输出二级菜单 ViewBag.menusecond_rights
        /// 输出操作菜单 ViewBag.right_actions
        /// </summary>
        /// <param name="rightCode"></param>
        public RoleAuthorizeAttribute(params string[] rightCodes)
        {
            RightCodes = rightCodes;
        }
        /// <summary>
        /// RightCodes
        /// </summary>
        public string[] RightCodes { get; private set; }

        /// <summary>
        /// 已使用到的变量参数(如不重新赋值，请勿覆盖)
        /// ViewBag.Title（标题）
        /// ViewBag.menutop_rights（头部目录菜单）
        /// ViewBag.menusecond_rights（左则目录菜单）
        /// ViewBag.table_actions（列表页的操作链接）
        /// </summary>
        /// <param name="filterContext"></param>     
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            try
            {
                var controller = filterContext.Controller as Controller;

                #region 权限分配
                ISysService sysService = IOCContainerManager.Resolve<ISysService>();
                CurrentUser cuser = sysService.GetCurrentUser(filterContext.HttpContext, CommonConst.AdminAuthenticationScheme);
                if (cuser != null)
                {
                    controller.ViewBag.CurrentUser = cuser;
                    IList<SysRight> list = sysService.GetSysRightListByRoleId(cuser.RoleId);
                    //判断权限值
                    if ((RightCodes != null) && list != null)
                    {
                        SysRight o = list.FirstOrDefault(a => RightCodes.Contains(a.ID));
                        if (o == null)
                        {
                            filterContext.HttpContext.Response.Clear();
                            filterContext.Result = new RedirectResult("/Admin/Account/Permission");
                            filterContext.HttpContext.Response.Redirect("/Admin/Account/Permission");
                            return;
                        }
                        controller.ViewBag.Title = o.RightName;
                        controller.ViewBag.menusecond_rights = list.Where(k => k.LevelCount > 1 && k.IsMenu == 1).OrderBy(a => a.SortNo).ToList();
                        //操作按钮
                        controller.ViewBag.right_actions = list.Where(a => a.ParentCode == o.ID && a.IsControl == 1).OrderBy(b => b.SortNo).ToList();
                        controller.ViewBag.table_actions = list.Where(a => a.ParentCode == o.ID && a.IsTableControl == 1).OrderBy(b => b.SortNo).ToList();
                        //当前权限ID及所有父级ID
                        List<string> currentrightlist = CommonHelper.GetCurrentParentCodeList(list, o.ParentCode);
                        currentrightlist.AddRange(RightCodes);
                        controller.ViewBag.current_rights = currentrightlist;
                        //顶级menu
                        controller.ViewBag.menutop_rights = list.Where(a => a.LevelCount == 1 && a.IsMenu == 1).OrderBy(b => b.SortNo).ToList();
                    }
                    else
                    {
                        filterContext.Result = RedirectToLogin(filterContext.HttpContext);
                        return;
                    }
                }
                else
                {
                    filterContext.Result = RedirectToLogin(filterContext.HttpContext);
                    return;
                }
                #endregion
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                filterContext.Result = RedirectToLogin(filterContext.HttpContext);
                return;
            }
        }

        /// <summary>
        /// 判断是否登录
        /// </summary>
        /// <param name="filterContext"></param>     
        public virtual void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            #region 判断是否登录
            try
            {
                //获取对应Scheme方案的登录用户呢？使用HttpContext.AuthenticateAsync
                var authenticate = filterContext.HttpContext.AuthenticateAsync(CommonConst.AdminAuthenticationScheme);
                //authenticate.Wait();
                if (authenticate.Result.Succeeded)
                {
                    var claimIdentity = authenticate.Result.Principal.Claims.ToList();
                    string loginIP = string.Empty;
                    if (claimIdentity.FirstOrDefault(s => s.Type == CommonConst.LoginIP) != null)
                    {
                        loginIP = claimIdentity.FirstOrDefault(s => s.Type == CommonConst.LoginIP).Value;
                    }
                    string currentIP = filterContext.HttpContext.GetIP();
                    if (loginIP.Equals(currentIP))
                    {
                        return;
                    }
                }

                //如果是默认Scheme可以使用 
                //if (filterContext.HttpContext.User.Identity.IsAuthenticated)
                //{
                //    return;
                //}

                RedirectResult redirectResult = RedirectToLogin(filterContext.HttpContext);
                filterContext.Result = redirectResult;
                return;
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                filterContext.Result = RedirectToLogin(filterContext.HttpContext);
                return;
            }
            #endregion
        }

        #region otherMethod
        private RedirectResult RedirectToLogin(HttpContext httpContext)
        {
            httpContext.SignOutAsync(CommonConst.AdminAuthenticationScheme);
            httpContext.Response.Clear();
            httpContext.Response.Redirect("/Admin/Account/Login");
            return new RedirectResult("/Admin/Account/Login");
        }
        #endregion

    }
}